﻿using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Kinespective
{
    public class AdaptiveVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        private double _adaptedFontSize = 40;

        public double AdaptiveFontSize
        {
            get { return _adaptedFontSize; }
            set
            {
                _adaptedFontSize = value;
                NotifyPropertyChanged();
            }
        }

        private double _xSlider;

        public double xSlider
        {
            get { return _xSlider; }
            set
            {
                _xSlider = value;
                NotifyPropertyChanged();
            }
        }

        private double _ySlider;

        public double ySlider
        {
            get { return _ySlider; }
            set
            {
                _ySlider = value;
                NotifyPropertyChanged();
            }
        }


        private KinectSensor _kinectSensor;
        private Skeleton[] _skeletons;

        public void StartKinect()
        {
            KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
            _kinectSensor = KinectSensor.KinectSensors.First(k => k.Status == KinectStatus.Connected);
            if (_kinectSensor != null)
                EnableKinectStream();
        }

        void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            if (e.Sensor != null)
            {
                _kinectSensor = e.Sensor;
                EnableKinectStream();
            }
        }
        private void EnableKinectStream()
        {
            _kinectSensor.SkeletonFrameReady += _kinectSensor_SkeletonFrameReady;
            _kinectSensor.SkeletonStream.Enable();
            _skeletons = new Skeleton[_kinectSensor.SkeletonStream.FrameSkeletonArrayLength];
            _kinectSensor.Start();
        }

        void _kinectSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (SkeletonFrame frame = e.OpenSkeletonFrame())
            {
                if (frame != null)
                {
                    frame.CopySkeletonDataTo(_skeletons);
                    Skeleton skeleton = _skeletons.OrderBy(s => s.Position.Z).Where(s => s.Position.Z > 0 && s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault();
                    if (skeleton != null)
                    {
                        this.AdaptiveFontSize = skeleton.Position.Z * 15d + 15d;

                        this.ySlider = Math.Tan(
                            skeleton.Joints[JointType.Head].Position.X
                            / skeleton.Joints[JointType.Head].Position.Z)
                            / Math.PI * 180d
                            / 1.7d; // manual FoV correction based on screen size

                        this.xSlider = -Math.Tan((skeleton.Joints[JointType.Head].Position.Y - .40d)
                            / skeleton.Joints[JointType.Head].Position.Z)
                            / Math.PI * 180d;
                    }
                }
            }
        }

        public void StopKinect()
        {
            if (_kinectSensor != null)
                _kinectSensor.SkeletonStream.Disable();
            _kinectSensor.Stop();
            _kinectSensor.Dispose();
        }
    }
}
